<template>
  <div class="pro-table-wrapper">
    <div class="action-box" v-if="editable">
      <add-button type="primary" @click="handleAddRow">新增</add-button>
    </div>
    <el-table
      ref="tableRef"
      :data="editableData"
      class="pro-table"
      v-bind="{ ...defaultOptions, ...$attrs }"
      @row-click="handleRowClick"
      @selection-change="$emit('selection-change')"
      @row-dblclick="$emit('row-dblclick')"
      @row-contextmenu="$emit('row-contextmenu')"
      @row-mouse-enter="$emit('row-mouse-enter')"
      @row-mouse-leave="$emit('row-mouse-leave')"
      @sort-change="$emit('sort-change')"
      @filter-change="$emit('filter-change')"
      @header-dragend="$emit('header-dragend')"
    >
      <el-table-column v-if="showIndex" type="index" label="序号" width="60" align="center" />
      <!-- 动态渲染所有列 -->
      <template v-for="column in newColumns" :key="column.prop || column.label">
        <el-table-column v-bind="column">
          <template #default="scope">
            <!-- 自定义插槽 -->
            <slot v-if="column.slot" :name="column.slot" v-bind="scope"></slot>
            <!-- 链接类型 -->
            <el-link
              v-else-if="column.type === 'link'"
              type="primary"
              @click="$emit('link-click', scope.row)"
            >
              {{ scope.row[column.prop] }}
            </el-link>

            <!-- 图标类型 -->
            <el-icon v-else-if="column.type === 'icon'">
              <component :is="scope.row[column.prop]" />
            </el-icon>

            <!-- 编辑文本框 -->
            <el-input
              v-else-if="column.editable && scope.row.isEditing"
              v-model="scope.row[column.prop]"
              placeholder="请输入"
              size="small"
            />
            <!-- 图片类型 -->
            <Image
              v-else-if="column.type === 'image' && scope.row[column.prop]"
              :src="scope.row[column.prop]"
              width="60"
              class="image-cell"
            />
            <component v-else :is="column.component || 'span'" v-bind="column.attrs?.(scope.row)">
              {{ column.render ? column.render(scope.row) : scope.row[column.prop] }}
            </component>
            <!-- <component v-else-if="column.type === 'component'" :is="column.component">
              {{ column.render ? column.render(scope.row) : scope.row[column.prop] }}
            </component>
            <span v-else-if="column.render">{{ column.render(scope.row) }}</span>
            <span v-else>{{ scope.row[column.prop] }}</span> -->
          </template>
        </el-table-column>
      </template>

      <!-- 操作列 -->
      <el-table-column label="操作" width="150" v-if="editable">
        <template #default="scope">
          <div v-if="scope.row.isEditing">
            <el-button size="small" @click="handleSaveRow(scope.$index)">保存</el-button>
            <el-button size="small" @click="handleCancelEdit(scope.$index)">取消</el-button>
          </div>
          <div v-else>
            <el-button size="small" @click="handleEditRow(scope.$index)">编辑</el-button>
            <el-button size="small" type="danger" @click="handleDeleteRow(scope.$index)">
              删除
            </el-button>
          </div>
        </template>
      </el-table-column>
    </el-table>

    <!-- 分页组件 -->
    <Pagination
      v-if="pagination && pagination?.total"
      v-bind="pagination"
      @pagination-change="handlePaginationChange"
      class="pagination-wrapper"
    />
  </div>
</template>

<script setup lang="ts">
  import { ElTable, ElButton, ElInput, ElLink, ElIcon, ElTableColumn } from 'element-plus'
  import Pagination from './Pagination/index.vue'
  import type { IColumn, ProPaginationProps } from './type'

  // 表格引用
  const tableRef = ref()

  // 定义事件
  const emit = defineEmits([
    'row-click',
    'link-click',
    'row-dblclick',
    'row-contextmenu',
    'row-mouse-enter',
    'row-mouse-leave',
    'selection-change',
    'sort-change',
    'filter-change',
    'header-dragend',
    'expand-change',
    'pagination-change'
  ])

  // 定义 props
  const props = defineProps({
    columns: {
      type: Array as () => IColumn<any>[],
      default: () => []
    },
    data: {
      type: Array as () => any[],
      default: () => []
    },
    showIndex: {
      type: Boolean,
      default: false
    },
    showSelection: {
      type: Boolean,
      default: false
    },
    pagination: {
      type: Object as () => ProPaginationProps
    },
    editable: {
      type: Boolean,
      default: false
    }
  })

  // 默认配置
  const defaultOptions = {
    border: true,
    stripe: true,
    showHeader: true,
    fit: true,
    emptyText: '暂无数据',
    rowKey: 'id',
    showOverflowTooltip: true,
    highlightCurrentRow: true
  }

  // 计算新列（包括索引列和选择列）
  const newColumns = computed(() => {
    const columns: IColumn[] = []
    if (props.showSelection) {
      columns.push({
        type: 'selection',
        width: 50,
        align: 'center',
        prop: 'selection'
      })
    }
    return [...columns, ...props.columns]
  })

  // 可编辑数据源
  const editableData = ref<any[]>([])

  // 初始化可编辑数据
  watchEffect(() => {
    editableData.value = props.data.map((item: any) => ({ ...item, isEditing: false }))
  })
  // 行/列合并
  // 行点击事件
  const handleRowClick = (row: Record<string, any>) => {
    if (props.showSelection) tableRef.value?.toggleRowSelection(row)
    emit('row-click', row)
  }

  // 分页改变事件
  const handlePaginationChange = (params: { pageIndex: number; pageSize: number }) => {
    emit('pagination-change', params)
  }

  // 添加新行
  const handleAddRow = () => {
    const newRow: Record<string, any> = {}
    props.columns.forEach((column: IColumn) => {
      column.prop && (newRow[column.prop!] = '')
    })
    newRow['isEditing'] = true
    editableData.value.push(newRow)
  }

  // 开始编辑
  const handleEditRow = (index: number) => {
    editableData.value[index].isEditing = true
  }

  // 保存修改
  const handleSaveRow = (index: number) => {
    editableData.value[index].isEditing = false
    // 触发保存事件，传出修改后的数据
    emit('save-row', editableData.value[index])
  }

  // 取消编辑
  const handleCancelEdit = (index: number) => {
    const originalRow = props.data.find((_: any, i: number) => i === index)
    editableData.value[index] = { ...originalRow, isEditing: false }
  }

  // 删除行
  const handleDeleteRow = (index: number) => {
    editableData.value.splice(index, 1)
  }
</script>

<style lang="scss" scoped>
  .pro-table-wrapper {
    height: 100%;
    /* flex: 1; 使用flex:1让表格容器自动撑满剩余空间 */
    /* min-height: 0; 解决flex容器下子元素高度溢出不显示的问题 */
    display: flex;
    flex-direction: column;
    .pro-table {
      flex: 1;
      .image-cell {
        width: 46px;
      }
    }

    .pagination-wrapper {
      margin-top: 15px;
      display: flex;
      justify-content: flex-end;
    }
  }
</style>
